package edu.umd.ion.wavemeter.server;

import java.util.Vector;

import edu.umd.ion.wavemeter.service.ChannelEvent;
import edu.umd.ion.wavemeter.service.ChannelRoutingInfo;
import edu.umd.ion.wavemeter.service.ServerParameters;
import edu.umd.ion.wavemeter.service.WavemeterException;
import edu.umd.ion.wavemeter.service.WavemeterSetException;

/**
 * @author pmaunz
 * Interface for the ChannelManager. 
 * The ChannelManager organized the mapping of the virtual channels seen by the clients
 * to the raw channels of the wavemeter. The implementing class controls the corresponding
 * hardware.
 */
public interface ChannelManager {
	/** 
	 *  To be called before exciting. Give up resources.
	 */
	public void cleanup();
	
	/** 
	 * Update the status of the Interlock
	 * @param virtchannel
	 * @param engage
	 */
	public void pushInterlock(int virtchannel, boolean engage);
	
	/**
	 * Report the status of a raw channel.
	 * @param rawchannel
	 * @param active
	 */
	public void setRawChannelState(int rawchannel, boolean active);
	
	/**
	 * Enable or Disable a virtual channel.
	 * @param virtchannel
	 * @param active
	 * @throws WavemeterException
	 */
	public void setChannelActive(int virtchannel, boolean active) throws WavemeterException;
	
	/**
	 * Lock or unlock a virtual channel to a raw channel for PID control.
	 * @param virtchannel
	 * @param locked
	 * @throws WavemeterException
	 */
	public void setChannelLocked(int virtchannel, boolean locked) throws WavemeterException;
	
	/**
	 * Register callbacks to be called to lock and unlock the PID regulator of a channel.
	 * This is necessary because locking can only happen after the routing of the channel 
	 * is exclusive.
	 * @param rawchannel
	 * @param lock
	 * @param unlock
	 */
	public void registerRawChannelCallback(int rawchannel, RunnableOne<Integer> lock , 
				RunnableOne<Integer> unlock);
	
	/**
	 * Report whether a wavelength measurement was successful or returned an error.
	 * This is used to keep track of how long a specific channel is in error state and 
	 * is therefore free to be dropped.
	 * @param rawchannel
	 * @param result
	 * @throws WavemeterException
	 */
	public void obtainedResult(int rawchannel, boolean result) throws WavemeterException;
	
	/**
	 *  Get Virtual Channel active for a specific raw channel
	 * @param rawchannel
	 * @return virtual channel
	 */
	public int activeVirtChannel(int rawchannel);
	
	/**
	 * Get Last Virtual Channel
	 * @param rawchannel
	 * @return virtual channel
	 */
	public int lastVirtChannel(int rawchannel);
	
	/**
	 * Schedule the next virtual channel for a rawchannel
	 * @param rawchannel
	 * @return virtual channel
	 * @throws WavemeterException
	 */
	public int scheduleChannel(int rawchannel) throws WavemeterException;
	
	/**
	 * Number of active Channels
	 * @return
	 */
	public int activeChannels();
	
	/**
	 * Lock the system for calibration
	 * @param virtchannel
	 * @return rawchannel to be used for calibration
	 * @throws WavemeterSetException
	 */
	public int calibrationChannelLock(int virtchannel) throws WavemeterSetException;
	
	/**
	 * Release the Calibration Lock
	 * @throws WavemeterSetException
	 */
	public void calibrationChannelUnlock() throws WavemeterSetException;
	
	/**
	 * Get the Channel Routing information
	 * @return
	 */
	public Vector<ChannelRoutingInfo> channelRouting();
	
	public void setParameters(ServerParameters param);
	public ServerParameters getParameters();
	public void raiseChannelEvent( ChannelEvent E);
}
